<template>
	<view class="previewLayout">
		<swiper circular :current="currentIndex" @change="swiperChange" skip-hidden-item-layout>
			<swiper-item v-for="(item,index) in classList" :key="item._id">
				<view class="swiper-item">
					<!-- 性能优化，通过v-if来控制只显示当前正在浏览的图片，节约资源 -->
				    <image v-if="readImgs.includes(index)" :src="item.picurl" mode="aspectFill" @click="maskChange"></image>	
				</view>
			</swiper-item>
		</swiper>
		<view class="mask" v-if="maskState">
			<view class="goBack" @click="goBack" :style="{top:getStatusBarHeight()+ 'px'}">
				<uni-icons type="back" color="#fff" size="20"></uni-icons>
			</view>
			<view class="count">{{ currentIndex + 1 }} / {{classList.length}}</view>
			<view class="time">
				<uni-dateformat :date="new Date()" format="hh:mm"></uni-dateformat>
			</view>
			<view class="data">
				<uni-dateformat :date="new Date()" format="MM月dd日"></uni-dateformat>
			</view>
			<view class="footer">
				<view class="box" @click="clickInfo">
					<uni-icons type="info" size="28"></uni-icons>
					<view class="text">
						信息
					</view>
				</view>
				<view class="box" @click="clickScore">
					<uni-icons type="star" size="28"></uni-icons>
					<view class="text">
						{{ currentInfo.score }}分
					</view>
				</view>
				<view class="box" @click="clickDowload">
					<uni-icons type="download" size="24"></uni-icons>
					<view class="text">
						下载
					</view>
				</view>
			</view>
		</view>
	    <uni-popup ref="infoPopup" type="bottom" border-radius="10rpx 10rpx 0 0">
			<view class="infoPopup">
				<view class="popHeader">
					<view class=""></view>
					<view class="title">壁纸信息</view>
					<view class="close" @click="clickInfoClose">
						<uni-icons type="closeempty" size="18" close="#999"></uni-icons>
					</view>
				</view>
				<scroll-view scroll-y>
					<view class="content">
						<view class="row">
							<view class="label">壁纸ID：</view>
							<text selectable class="value">{{ currentInfo._id }}</text>
						</view>
						<!-- <view class="row">
							<view class="label">分类：</view>
							<text selectable class="value class">{{}}</text>
						</view> -->
						<view class="row">
							<view class="label">发布者：</view>
							<text selectable class="value">{{ currentInfo.nickname }}</text>
						</view>
						<view class="row">
							<view class="label">评分：</view>
							<view class="value rateBox">
								<uni-rate :value="currentInfo.score" readonly touchable/>
								<text class="score">{{currentInfo.score}}分</text>
							</view>
						</view>
						<view class="row">
							<view class="label">摘要：</view>
							<text selectable class="value ">{{ currentInfo.description }}</text>
						</view>
						<view class="row">
							<view class="label">标签：</view>
							<view class="value tabs">
								<view class="tab" v-for="(item,index) in currentInfo.tabs" :key="index">
								   {{ item }}
								</view>
							</view>
						</view>
						<view class="copyright">
							声明:本图片来用户投稿，非商业使用，用于免费学习交流，如侵犯了您的权益，您可以拷贝壁纸ID举报至平台，邮箱513894357@qq.com，管理将删除侵权壁纸维护您的权益。
						</view>
					</view>
				</scroll-view>
			</view>
		</uni-popup>
	    <uni-popup ref="scorePopup" type="center" border-radius="10rpx" :is-mask-click="false">
			<view class="scorePopup">
				<view class="popHeader">
					<view class=""></view>
					<view class="title">{{ isScore?"您已经评分过了":"壁纸评分" }}</view>
					<view class="close" @click="clickScoreClose">
						<uni-icons type="closeempty" size="18" close="#999"></uni-icons>
					</view>
				</view>
				<view class="content">
					<uni-rate  v-model="reatUserValue" allowHalf :readonly="isScore" />
					<text>{{ reatUserValue }} 分</text>
				</view>
				<view class="footer">
					<button type="default" :disabled="!reatUserValue || isScore" plain size="mini" @click="submitScore">确认评分</button>
				</view>
			</view>
		</uni-popup>
	</view>
</template>

<script setup>
    import { ref } from 'vue';
	import { getStatusBarHeight } from '@/utils/system.js';
	import { onLoad,onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app';
	import { apiGetSetupScore, apiWriteDownload, apiDetailWall } from '../../api/apis';
	
    // 遮罩层状态
	const maskState = ref(true)
	// 信息 弹出框
	const infoPopup = ref(null)
	// 评分 弹出框
	const scorePopup = ref(null)
	// 信息 评分分数
	const rateInfoValue = ref(5)
	// 用户评分
	const reatUserValue = ref(0)
	// 处理后的数组
	const classList = ref([])
	const currentId = ref(null)
	const currentIndex = ref(-1)
	// 当前点击的壁纸的信息
	const currentInfo = ref({})
	// 预加载前中后三张图片，保证实现用户体验的同时，节省性能。
	const readImgs = ref([])
	// 受否已经评分
	const isScore = ref(false)
	
	// 在onLoad生命周期里 拿到从 list传递过来的id
	onLoad(async(e)=>{
		currentId.value = e.id;
		
		if(e.type == 'share'){
			// 如果是分享进来的  我们需要单独请求这个壁纸的信息
			let res = await apiDetailWall({id:e.id})
			classList.value = res.data.map(item=>{
		    return {
		    	...item,
		    	picurl: item.smallPicurl.replace("_small.webp",".jpg")
		    }
	})
		}
		currentIndex.value= classList.value.findIndex(item=>item._id == currentId.value)
		currentInfo.value = classList.value[currentIndex.value]
		readImgsFun()
	})
	
	// 滑动事件
	const swiperChange = (e) => {
		 currentIndex.value = e.detail.current
		 currentInfo.value = classList.value[currentIndex.value]
		 readImgsFun()
	}
	
	//抽离预加载的前后各一张图片
	const readImgsFun = () => {
		// 在初始加载时，预加载前后各一张图片
		readImgs.value.push(
		    // 判断是否为第一张是的话提前加载最后一张
		    currentIndex.value == 0?classList.value.length-1 : currentIndex.value - 1,  
		    currentIndex.value,
		    // 判断是否是最后一张是的话提前加载第一张
		    currentIndex.value == classList.value.length-1?0 : currentIndex.value + 1
		)
		readImgs.value = [...new Set(readImgs.value)]
	}
	 
	// 从浏览器缓存中拿到数据
	const storageClassList = uni.getStorageSync("storageClassList") || []
	classList.value = storageClassList.map(item=>{
		// 点击图片的大图，因为接口中没有返回大图.jpg格式，只返回了webp格式的小图，所以我们需要循环一下统一处理
		return {
			...item,
			picurl: item.smallPicurl.replace("_small.webp",".jpg")
			// return一个新对象  属性值是item的展开 如果item原本有 picurl，则会被新值覆盖；如果原本没有，则新增这个属性。
		}
	})
	
	// 遮罩显示与隐藏
	const maskChange = () => {
		maskState.value = !maskState.value
	}
	// 点击信息弹出底部弹窗
	const clickInfo = () => {
		console.log(infoPopup.value)
		infoPopup.value.open()
	}
	// 点击关闭底部弹窗
	const clickInfoClose = () => {
		infoPopup.value.close()
	}
	// 点击关闭评分弹窗
	const clickScoreClose = () => {
		scorePopup.value.close()
		isScore.value = false
		setTimeout(()=>{reatUserValue.value = 0},500)
	}
	// 评分
	const clickScore = () => {
		if(currentInfo.value.userScore){
			isScore.value = true
			reatUserValue.value = currentInfo.value.userScore
		} 
		scorePopup.value.open()
	}
	// 提交评分
	const submitScore = async () => {
		// 优化体验
		uni.showLoading({
			title:"加载中"
		})
		// _id:wallId 结构出来并改名
		const { classid,_id:wallId } = currentInfo.value
		const res = await apiGetSetupScore({
			classid,
			wallId,
			userScore:reatUserValue.value,
		})
		uni.hideLoading()
		if(res.errCode === 0){
			uni.showToast({
				title: "评分成功",
				icon: "none"
			})
			classList.value[currentIndex.value].userScore = reatUserValue.value
			uni.setStorageSync("storageClassList",classList.value)
			scorePopup.value.close()
		}
		
		
	}
	// 返回上一页
	const goBack = () => {
		uni.navigateBack({
			success: ()=>{},
			fail: () => {
				// 如果我们是分享进入了此页面 必定无法返回上一页，并报错 
				// 此时我们需要给他直接返回首页即可
				uni.reLaunch({
					url:"/pages/index/index"
				})
			}
		})
	}
    // 点击下载
	const clickDowload = async() => {
		// #ifdef H5
		uni.showModal({
            // 弹出弹窗的api
		    content:"长按保存壁纸",
		    showCancel:false,
		})
		// #endif
		
		// #ifndef H5
		try{
		uni.showLoading({
			title:"下载中...",
			mask:true
		})
		
		const { classid,_id:wallId } = currentInfo.value
		// 将下载的图片进行提交，因为个人中心有一个已下载的图片列表
		const res = await apiWriteDownload({
			classid,
			wallId
		})
		if(res.errCode != 0) throw res; //在trycatch中相当于 return
		 
		
		// 首先我们要去小程序开发平台 开发管理 开发设置 服务器域名
		//  request合法域名	以及downloadFile合法域名（下载资源的合法域名，我们此项目将是将图片放在cdn上了）
		
		// uni.getImageInfo() 会根据路径下载图片并生成一个临时文件路径，以及返回相关的图片信息。
		uni.getImageInfo({
			src: currentInfo.value.picurl, 
			success: (res) => {
				// console.log(currentInfo.value)
				// console.log(res,'图片的相关信息和路径')
		
				// 媒体=>图片=>保存图片到系统相册的api uni.saveImageToPhotosAlbum(OBJECT)
				uni.saveImageToPhotosAlbum({
					filePath: res.path,  //将uni.getImageInfo生成的临时图片地址进行配置，其实配置到这一步就已经完成了
					success:(result)=>{
						// 用户点击 允许授权图片下载
						console.log(result)
						uni.showToast({
							title:"保存成功，请到相册查看",
							icon:"none",
						})
					},
					fail: (err)=>{
						// 用户点击拒绝授权之后需要给用户第二次机会 不能以后永远没法授权了，因此我们给他一个弹窗 并调用 uni.openSetting 来拉起手机的权限设置
						// console.log(err)
						if(err.errMsg == "saveImageToPhotosAlbum:fail cancel"){
							// 取消保存也是下载失败 与 未授权都是走这边 所以我们要判断一下 是否弹出下面未授权的提示弹框，如果是因为取消保存所产生的问题 我们return出去
							// 拒绝授权的报错信息 是 saveImageToPhotosAlbum:fail auth deny
							// 取消保存的报错信息 是 saveImageToPhotosAlbum:fail cancel
							uni.showToast({
								title:"保存失败，请重新下载",
								icon:"none"
							})
							return
						}
						uni.showModal({
							title:"提示",
							content:"需要授权保存相册",
							success:res=>{
								if(res.confirm){
									uni.openSetting({  //拉起手机授权设置
										success(setting){
											// console.log(setting)
											if(setting.authSetting['scope.writePhotosAlbum']) //看打印结果  这个是点了重新开启的滑块
											{
												uni.showToast({
													title:"获取授权成功",
													icon:'none',
												})
											}
											else {
												uni.showToast({
													title:"获取授权失败",
													icon:'none',
												})
											}
										}
									})
								}
							}
						})
					},
					complete: () => {
						// complete 无论成功还是失败  我们后面都要把 loading弹窗取消掉
						uni.hideLoading()
					}
				})
			} 
		})
		}catch(err){
			console.log(err)
			uni.hideLoading()
		}
		// #endif
	}
	// 分享给好友  aip->第三方服务->分享
	onShareAppMessage(()=>{
		return {
			title:`咸虾米壁纸,精选分类`,
			path:`/pages/previw/previw?id=${currentInfo.value._id}&type=share`  
			//分享到具体分类  但是如果要是微信分享到当前页面的话，对方是直接跳转到这一页，拿不到上一页的浏览器缓存classList的数据，因此我们需要再自己定义一个type，并且再onload中进行判断并单独请求接口
		} 
	})
	// 分享到 微信朋友圈 微信小程序开发平台去看相关api
	onShareTimeline(()=>{
		return {
			title:`咸虾米壁纸,精选分类`,  //分享给别人的title
			imageUrl: "/static/images/xxmLogo.png",  
			query:`id=${currentInfo.value._id}&type=share`, //分享微信朋友圈时 不需要带前面的页面路径 ，参数的key值是query
		}
	})
</script>

<style lang="scss" scoped>
	.previewLayout {
		width: 100%;
		height: 100vh;
		position: relative;
		swiper {
			width: 100%;
			height: 100%;
			image {
				width: 100%;
				height: 100vh;
			}
		}
		.mask {
			&>view {
			// 父元素 下面的所有的 view 都有的样式
				position: absolute;
				left: 0;
				right: 0;
				margin: auto;
				width: fit-content;
			}
			.goBack {
				width: 38px;
				height: 38px;
				background: rgba(0, 0, 0, 0.5);
				left: 30rpx;
				margin-left: 0;
				border-radius: 100px;
				top: 0;
				backdrop-filter: blur(10rpx);
				border: 1rpx solid rgba(255, 255, 255, 0.3);
				display: flex;
				justify-content: center;
                align-items: center;
			}
			.count {
				position: absolute;
				top: 10vh;
				
				// 在使用定位的情况下 ，怎么剧中对齐  left 0  right 0 margin auto
				left: 0;
				right: 0;
				margin: auto;
				width: fit-content;  //自动判断 有多少内容 整多宽
				backdrop-filter: blur(10rpx);
				
				font-size: 20rpx;
				color: #fff;
				border-radius: 40rpx;
				background: rgba(0, 0, 0, 0.3);
                padding: 8rpx 28rpx;
			}
			.time {
				font-size: 140rpx;
				top: calc(10vh + 80rpx);
				color: #fff;
				font-weight: 100;
				line-height: 1em;
				text-shadow: 0 4rpx rgba(0,0,0,0.3 );
			}
			.data {
				font-size: 34rpx;
				color: #fff;
				top: calc(10vh + 226rpx);
				text-shadow: 0 2rpx rgba(0,0,0,0.3 );
			}
			.footer {
				background: rgba(255,255,255,0.8);
				bottom: 10vh;
				width: 65vw;
				height: 120rpx;
				border-radius: 120rpx;
				color: #000;
				display: flex;
				justify-content: space-around;
				align-items: center;
				box-shadow: 0 2rpx 0 rgba(0,0,0,0.1);
				backdrop-filter: blur(20rpx);
				.box {
					display: flex;
					flex-direction: column;
					align-items: center;
					justify-content: center;
					padding: 2rpx 12rpx;
					.text {
						font-size: 26rpx;
						color: $text-font-color-2;
					}
				}
			}
		}
		.popHeader {
			display: flex;
			justify-content: space-between;
			align-items: center;
			.title {
				color: $text-font-color-2;
				font-size: 26rpx;
			}
			.close {
				padding: 6rpx;
			}
		}
	    .infoPopup {
			background-color: #fff;
			padding: 30rpx;
			padding-bottom: 60rpx;
			border-radius: 30rpx 30rpx 0 0;
			scroll-view {
				max-height: 60vh;
				.content {
					.row {
						display: flex;
						padding: 16rpx 0;
						font-size: 32rpx;
						line-height: 1.7em;
						.label {
							color: $text-font-color-3;
							width: 140rpx;
							text-align: right;
							font-size: 30rpx;
						}
						.value {
							flex: 1;
							width: 0;
						}
						.class {
							color: $brand-theme-color;
						}
						.rateBox {
							display: flex;
							align-items: center;
							.score {
								font-size: 26rpx;
								color: $text-font-color-2;
								padding-left: 10rpx;
							}
						}
						.tabs {
							display: flex;
							flex-wrap: wrap;
							.tab {
								border: 1px solid $brand-theme-color;
								color: $brand-theme-color;
								font-size: 22rpx;
								padding: 10rpx 30rpx;
								border-radius: 40rpx;
								line-height: 1em;
								margin: 0 10rpx 10rpx 0;
							}
						}
					}
				    .copyright {
						font-size: 28rpx;
						padding: 20rpx;
						background-color: #f6f6f6;
						color: #666;
						border-radius: 10rpx;
						margin: 20rpx 0;
						line-height: 1.6em;
					}
				}
			}
		}
	    .scorePopup {
		    background-color: #fff;
			padding: 30rpx;
			width: 70vw;
			border-radius: 30rpx;
			.content {
				font-size: 28rpx;
				padding: 30rpx 0;
				display: flex;
				justify-content: center;
				align-items: center;
				text {
					color: #ffca3e;
					padding-left: 10rpx;
					width: 80rpx;
					line-height: 1em;
					text-align: right;
				}
			}
			.footer {
				padding: 10rpx 0;
				display: flex;
				justify-content: center;
				align-items: center;
			}
		}
	}       
</style>
